#include <time.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#include <libxml/tree.h>

static void usage(const char *name);
static xmlNodePtr createMneme(const char *text);
static char *strjoin(const char* first, ...);

int
main (int argc, char **argv)
{
	if (argc != 2) {
		fprintf(stderr, "Oups! wrong number of arguments!\n");
		usage(argv[0]);
		return (-1);
	}

	xmlDocPtr d;
	xmlNodePtr mnemes, mneme;

	// Load XML document.
	char *fname = strjoin("/", getenv("HOME"), ".mnemes.xml", NULL);

	d = xmlParseFile(fname);
	if (d == NULL) {
		// Create new document.
		d = xmlNewDoc(BAD_CAST "1.0");

		// Create mnemes container element.
		mnemes = xmlNewNode(NULL, BAD_CAST "mnemes");
		xmlDocSetRootElement(d, mnemes);
	}
	else
	{
		// Find the mnemes root element.
		if ((mnemes = xmlDocGetRootElement(d)) == NULL) {
			fprintf(stderr, "Oups! this file does not seem as a mnemes file.\n");
			return (-1);
		}
	}

	// Add mneme to mnemes and set it's content.
	mneme = createMneme(argv[1]);
	xmlAddChild(mnemes, mneme);

	FILE *f;
	f = fopen(fname, "w+");
	xmlDocFormatDump(f, d, 1);
	fclose(f);

	return 0;
}

xmlNodePtr
createMneme(const char *text)
{
	assert(text);

	xmlNodePtr mneme = xmlNewNode(NULL, BAD_CAST "mneme"),
		   mnemeDate = xmlNewNode(NULL, BAD_CAST "updated"),
		   mnemeContent = xmlNewNode(NULL, BAD_CAST "content");

	char s[256];
	time_t t;
	t = time(NULL);
	struct tm *tmp;
	tmp = localtime(&t);
	strftime(s, sizeof(s), "%a, %d %b %Y %H:%M:%S %z", tmp);

	xmlNodeSetContent(mnemeDate, BAD_CAST s);
	xmlAddChild(mneme, mnemeDate);

	// TODO Safe check text.
	xmlNodeSetContent(mnemeContent, BAD_CAST text);
	xmlAddChild(mneme, mnemeContent);

	return mneme;
}

void
usage(const char *name) {
}

char
*strjoin(const char *separator, ...)
{
	char *string, *s;
	va_list args;
	int len;
	int separator_len;

	if (separator == NULL)
		separator = "";

	separator_len = strlen(separator);
	va_start(args, separator);
	s = va_arg(args, char *);

	if (s) {
		len = strlen(s);
		s = va_arg(args, char *);

		while (s) {
			len += separator_len + strlen(s);
			s = va_arg(args, char *);
		}
		va_end(args);
		string = malloc(sizeof(char) * (len + 1));

		*string = 0;
		va_start(args, separator);
		s = va_arg(args, char *);

		strcat(string, s);
		s = va_arg(args, char *);

		while (s) {
			strcat(string, separator);
			strcat(string, s);
			s = va_arg(args, char *);
		}
	} else
		string = ""; // strdup?
	va_end(args);

	return string;
}
